/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.usc.cs576.lib.mediaObject;

import edu.usc.cs576.lib.Action;
import edu.usc.cs576.lib.MediaObject;
import edu.usc.cs576.lib.Monitor.LoadingMonitor;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * basic object for video
 * @author haoxu
 */
public class Video implements MediaObject {

    String filepath;
    String filename;
    ArrayList<Image> images;
    int width;
    int height;
    File videoFile;
    byte[] bytes;
    int total_len;
    int single_len;
    int x;
    int y;
    int resize_x;
    int resize_y;
    ArrayList<Action> actions;
    int startFrame;
    int endFrame;

    public Video() {
        images = new ArrayList<Image>();
        width = -1;
        height = -1;
    }

    public void prepare() {
        videoFile = new File(filepath);
        total_len = (int) videoFile.length();
        single_len = this.getHeight() * this.getWidth() * 3;
        bytes = new byte[(int) total_len];
        LoadingMonitor.TOTAL_SIZE = (double) bytes.length;
    }

    public void load() {
        InputStream is = null;
        LoadingMonitor.LOAD_FINISHED = false;
        try {
            is = new FileInputStream(videoFile);

            int offset = 0;
            int numRead = 0;
            int readsize = single_len;

            int count = 0;
            while (offset < bytes.length) {
                numRead = is.read(bytes, offset, readsize);
                if (numRead >= 0) {
                    Image image = new Image();
                    int ind = count * this.getHeight() * this.getWidth() * 3;
                    BufferedImage bimage = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
                    //read the data
                    for (int y = 0; y < this.getHeight(); y++) {
                        for (int x = 0; x < this.getWidth(); x++) {
                            byte r = bytes[ind];
                            byte g = bytes[ind + this.getHeight() * this.getWidth()];
                            byte b = bytes[ind + this.getHeight() * this.getWidth() * 2];
                            int pix = 0xff000000 | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
                            bimage.setRGB(x, y, pix);
                            ind++;
                        }
                    }
                    image.setWidth(this.getWidth());
                    image.setHeight(this.getHeight());
                    image.setImage(bimage);

                    this.getImages().add(image);
                    offset += numRead;
                    LoadingMonitor.LOAD_SIZE = (double) offset;
                    count++;
                }
            }

            LoadingMonitor.LOAD_FINISHED = true;
        } catch (IOException ex) {
            Logger.getLogger(Video.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                is.close();
            } catch (IOException ex) {
                Logger.getLogger(Video.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void show() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public String getFilepath() {
        return filepath;
    }

    public void setFilepath(String filepath) {
        this.filepath = filepath;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public ArrayList<Image> getImages() {
        return images;
    }

    public void setImages(ArrayList<Image> images) {
        this.images = images;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getResize_x() {
        return resize_x;
    }

    public void setResize_x(int resize_x) {
        this.resize_x = resize_x;
    }

    public int getResize_y() {
        return resize_y;
    }

    public void setResize_y(int resize_y) {
        this.resize_y = resize_y;
    }

    public ArrayList<Action> getActions() {
        if (actions == null) {
            actions = new ArrayList<Action>();
        }
        return actions;
    }

    public void setActions(ArrayList<Action> actions) {
        this.actions = actions;
    }

    @Override
    public String toString() {
        return "Video{" + "filepath=" + filepath + "filename=" + filename + "images=" + images + "width=" + width + "height=" + height + "videoFile=" + videoFile + "bytes=" + bytes + "total_len=" + total_len + "single_len=" + single_len + "x=" + x + "y=" + y + "resize_x=" + resize_x + "resize_y=" + resize_y + '}';
    }

    public String getName() {
        return this.filename;
    }

    public void setStartFrame(int frame) {
        this.startFrame = frame;
    }

    public int getStartFrame() {
        return this.startFrame;
    }

    public void setEndFrame(int frame) {
        this.endFrame = frame;
    }

    public int getEndFrame() {
        return this.endFrame;
    }

    public void setName(String name) {
        this.filename = name;
    }
}
